#include "page_envmonitor.h"
#include "ui_page_envmonitor.h"
#include <QMessageBox>
#include <QThread>
#include <QProcess>
#include "widget.h"

#define SERIAL_PORT "/dev/ttymxc2" //串口号

// "/dev/ttymxc2"  对应UART3接口中的485和232共用的

// 命令帧数据
const QByteArray command1 = QByteArray::fromHex("01 03 00 00 00 04 44 09");

Page_envMonitor::Page_envMonitor(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Page_envMonitor),
    timer(new QTimer(this))
{
    ui->setupUi(this);

    m_history = new history();

    connect(m_history, &history::backToMainPage, this, [&]() {
        this->show();
        m_history->close();
    });

    // 创建串口对象
    serial = new QSerialPort(this);


    connect(serial, SIGNAL(readyRead()), this, SLOT(serialPort_readyRead())); // 监听串口应答
    connect(timer, SIGNAL(timeout()), this, SLOT(sendCommand1()));

    setupPlots();
    startTime1.start();

    on_pushButton_3_clicked();

    // 初始化数据库连接
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("sensor_data.db");
    if (!db.open()) {
        qDebug() << "Failed to open database!";
        return;
    }

    // 创建 meta_data 表
    QSqlQuery query;
    query.exec("CREATE TABLE IF NOT EXISTS meta_data ("
               "table_name TEXT PRIMARY KEY, "
               "start_time DATETIME NOT NULL, "
               "end_time DATETIME NOT NULL)");


}

Page_envMonitor::~Page_envMonitor()
{
    delete ui;
}

void Page_envMonitor::on_pBtn_back_clicked()
{
    this->hide();
    emit backToMainPage();

}

void Page_envMonitor::serialPort_readyRead()     //*串口接收
{
    static QByteArray responseBuffer; // 定义一个缓冲区存储接收的数据
    responseBuffer += serial->readAll(); // 将接收的数据追加到缓冲区
    // 检查缓冲区中是否包含完整的应答帧
    if (responseBuffer.length() >= 9) {
        QByteArray response1 = responseBuffer.left(13); // 提取完整的应答帧

        // 打印输出应答帧
        QString hexString = response1.toHex().toUpper();
        qDebug() << hexString;

        // 提取湿度值、温度值和光照值
        // 湿度值在第4和第5个字节
        QByteArray humidityBytes = response1.mid(3, 2);
        int humidity = (static_cast<unsigned char>(humidityBytes[0]) << 8) + static_cast<unsigned char>(humidityBytes[1]);
        float humidityFloat = humidity / 10.0;

        // 温度值在第6和第7个字节
        QByteArray temperatureBytes = response1.mid(5, 2);
        int temperatureRaw = (static_cast<unsigned char>(temperatureBytes[0]) << 8) + static_cast<unsigned char>(temperatureBytes[1]);
        if (temperatureBytes.at(0) == 0xFF) { // 如果最高位为FF，表示温度为负
            temperatureRaw -= 0x10000;
        }
        float temperature = temperatureRaw / 10.0;

        // 光照值在第8和第11个字节
        QByteArray illuminationBytes = response1.mid(7, 4);
        int illumination = (static_cast<unsigned char>(illuminationBytes[0]) << 24) +
                           (static_cast<unsigned char>(illuminationBytes[1]) << 16) +
                           (static_cast<unsigned char>(illuminationBytes[2]) << 8) +
                           static_cast<unsigned char>(illuminationBytes[3]);
        float illuminationFloat = static_cast<float>(illumination);

        // 显示湿度值、温度值和光照值
        ui->label->setText(QString("温度值：%1 ℃").arg(temperature));
        ui->label_2->setText(QString("湿度值：%1 %RH").arg(humidityFloat));
        ui->label_3->setText(QString("光照值：%1 Lux").arg(illuminationFloat));

        QDateTime currentTime = QDateTime::currentDateTime();
        if (currentTime.date() != lastTimestamp.date()) {
//            updateMetaData(currentTableName, lastTimestamp.date().endOfDay());
//            createNewTable(currentTime.date().startOfDay());
            // 获取一天的结束时间
            QDateTime endOfDay = QDateTime(currentTime.date(), QTime(23, 59, 59));
            updateMetaData(currentTableName, endOfDay);

            // 获取新一天的开始时间
            QDateTime startOfDay = QDateTime(currentTime.date().addDays(1), QTime(0, 0, 0));
            createNewTable(startOfDay);
        }

        recordSensorData(currentTime, temperature, humidityFloat, illuminationFloat);

        QProcess process;

        // 检查温度值并发送相应的命令
        if (temperature > Widget::temperatureThreshold) {
            process.start("sh", QStringList() << "-c" << "echo 1 > /sys/class/leds/beep/brightness");
        } else {
            process.start("sh", QStringList() << "-c" << "echo 0 > /sys/class/leds/beep/brightness");
        }

        // 等待进程执行完成
        process.waitForFinished();

        // 绘制折线图
        double key = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0;

        temperatureGraph->addData(key, temperature);
        humidityGraph->addData(key, humidityFloat);
        illuminationGraph->addData(key, illuminationFloat);

        ui->widget_1->xAxis->setRange(key, 60, Qt::AlignRight);
        ui->widget_1->replot();

        ui->widget_2->xAxis->setRange(key, 60, Qt::AlignRight);
        ui->widget_2->replot();

        ui->widget_3->xAxis->setRange(key, 60, Qt::AlignRight);
        ui->widget_3->replot();

        // 清空缓冲区，去除已处理的数据
        responseBuffer.clear();
    }

}


void Page_envMonitor::on_pushButton_clicked() // “发送信号”按钮
{
    // 发送消息1
//    serial->write(command1); //发送字节数组
//    qDebug() << "发送命令" << command1;

    startTime = QDateTime::currentDateTime();
    createNewTable(startTime);
    timer->start(500); // 启动定时器，每秒发送一次命令
    qDebug() << "定时器启动，每秒发送命令";
}

//void Page_envMonitor::on_pushButton_2_clicked() //“串口关闭”按钮
//{
//    serial->close();
//    timer->stop(); // 停止定时器
//    qDebug() << "串口关闭";
//}

void Page_envMonitor::on_pushButton_3_clicked() //“串口连接”按钮
{
    // 设置串口参数
    serial->setPortName(SERIAL_PORT);
    serial->setBaudRate(QSerialPort::Baud9600); //设置波特率
    serial->setDataBits(QSerialPort::Data8); //设置数据位
    serial->setStopBits(QSerialPort::OneStop); //设置停止位为1
    serial->setParity(QSerialPort::NoParity); //设置奇偶校验位

    // 设置流控制
    serial->setFlowControl(QSerialPort::NoFlowControl);

    // 打开串口
    serial->open(QIODevice::ReadWrite);
//    if (serial->open(QIODevice::ReadWrite)) {
//        // 串口打开成功，可以进行通信操作
//        qDebug() << "串口打开";
//    }
//    else {
//        // 串口打开失败，处理错误情况
//        QMessageBox::critical(nullptr, "错误", "无法打开串口！");
//        return;
//    }

}

void Page_envMonitor::on_pushButton_4_clicked()
{
    timer->stop(); // 停止定时器
    updateMetaData(currentTableName, QDateTime::currentDateTime());
    qDebug() << "停止定时器";
}

void Page_envMonitor::sendCommand1()
{
    serial->write(command1); //发送字节数组
    qDebug() << "发送命令" << command1;
}

void Page_envMonitor::setupPlots()
{
    // 设置温度折线图
    ui->widget_1->addGraph();
    temperatureGraph = ui->widget_1->graph(0);
    temperatureGraph->setPen(QPen(Qt::red));
    temperatureGraph->setName("Temperature");

    // 设置湿度折线图
    ui->widget_2->addGraph();
    humidityGraph = ui->widget_2->graph(0);
    humidityGraph->setPen(QPen(Qt::blue));
    humidityGraph->setName("Humidity");

    // 设置光照度折线图
    ui->widget_3->addGraph();
    illuminationGraph = ui->widget_3->graph(0);
    illuminationGraph->setPen(QPen(Qt::green));
    illuminationGraph->setName("illumination");

    // 配置x轴为时间轴
    QSharedPointer<QCPAxisTickerDateTime> timeTicker(new QCPAxisTickerDateTime);
    timeTicker->setDateTimeFormat("hh:mm:ss");

    ui->widget_1->xAxis->setTicker(timeTicker);
    ui->widget_1->xAxis->setTickLabelRotation(45);
    ui->widget_1->axisRect()->setupFullAxesBox();
    ui->widget_1->yAxis->setLabel("Temperature (°C)");
    ui->widget_1->yAxis->setRange(10, 40);

    ui->widget_2->xAxis->setTicker(timeTicker);
    ui->widget_2->xAxis->setTickLabelRotation(45);
    ui->widget_2->axisRect()->setupFullAxesBox();
    ui->widget_2->yAxis->setLabel("Humidity (%RH)");
    ui->widget_2->yAxis->setRange(0, 100);

    ui->widget_3->xAxis->setTicker(timeTicker);
    ui->widget_3->xAxis->setTickLabelRotation(45);
    ui->widget_3->axisRect()->setupFullAxesBox();
    ui->widget_3->yAxis->setLabel("illumination (Lux)");
    ui->widget_3->yAxis->setRange(0, 2000);

}



void Page_envMonitor::on_setting_clicked()
{
    this->hide();
    m_history->show();
}

void Page_envMonitor::createNewTable(const QDateTime &timestamp) {
    QString tableName = "data_" + timestamp.toString("yyyyMMdd_HHmmss");
    currentTableName = tableName;

    QSqlQuery query;
    QDateTime currentTime = QDateTime::currentDateTime();
    lastTimestamp = currentTime;
    query.exec("INSERT INTO meta_data (table_name, start_time, end_time) VALUES ('" + tableName + "', '" + timestamp.toString("yyyy-MM-dd HH:mm:ss") + "', '" + timestamp.toString("yyyy-MM-dd HH:mm:ss") + "')");

    query.exec("CREATE TABLE " + tableName + " ("
               "timestamp DATETIME PRIMARY KEY, "
               "temperature REAL, "
               "humidity REAL, "
               "illumination REAL)");
}

void Page_envMonitor::updateMetaData(const QString &tableName, const QDateTime &endTime) {
    QSqlQuery query;
    query.prepare("UPDATE meta_data SET end_time = :end_time WHERE table_name = :table_name");
    query.bindValue(":end_time", endTime.toString("yyyy-MM-dd HH:mm:ss"));
    query.bindValue(":table_name", tableName);
    query.exec();
}

void Page_envMonitor::recordSensorData(const QDateTime &timestamp, double temperature, double humidity, double illumination) {
    QSqlQuery query;
    query.prepare("INSERT INTO " + currentTableName + " (timestamp, temperature, humidity, illumination) "
                  "VALUES (:timestamp, :temperature, :humidity, :illumination)");
    query.bindValue(":timestamp", timestamp.toString("yyyy-MM-dd HH:mm:ss"));
    query.bindValue(":temperature", temperature);
    query.bindValue(":humidity", humidity);
    query.bindValue(":illumination", illumination);
    query.exec();
}
